﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using System.Text;
using System.Reflection;

namespace Mr.LinqToWeibo
{
    internal class ExpressionTreeModifier<T> : ExpressionVisitor
    {
        private IQueryable queryableObjects;

        internal ExpressionTreeModifier(object objects)
        {
            if (objects == null)
            {
                throw new ArgumentNullException("objects");
            }

            this.queryableObjects = ((IList<T>)objects).AsQueryable();

        }

        internal object GetFilterObjects(Expression expression)
        {
            Expression queryableExperssion = this.Visit(expression);
            return this.queryableObjects.Provider.Execute<IEnumerable<T>>(queryableExperssion);
        }

        protected override Expression VisitConstant(ConstantExpression c)
        {
            if (c.Type.Name == typeof(QueryableWeiboData<>).Name)
                return Expression.Constant(this.queryableObjects);
            else
                return c;
        }

        protected override Expression VisitMethodCall(MethodCallExpression m)
        {
            if (m.Method.Name == "Skip" || m.Method.Name == "Take")
            {
                return base.Visit(m.Arguments[0]);
            }
            return base.VisitMethodCall(m);
        }

        protected override Expression VisitBinary(BinaryExpression b)
        {
            MemberExpression memberExpression = ExpressionTreeHelpers.GetRootParameterMemberExpression(b);
            if (memberExpression != null)
            {
                string name = memberExpression.Member.Name;
                if (name == "KeyWord" || name == "Feature" || name == "BaseApp")
                {
                    return Expression.Constant(true);
                }
            }
            return base.VisitBinary(b);
        }
    }
}